import router from './router'
import store from './store/index'
import { Message } from 'element-ui'
import { Local } from '@/util/storage/storage.js'
import { Session } from '@/util/storage/session.js'
import { defaultRoute } from "@/util/defaultRoute"
import axios from 'axios'
import { refreshToken } from './request/user.js'
// import NProgress from 'nprogress' // progress bar
// import 'nprogress/nprogress.css' // progress bar style
// import { getToken } from '@/utils/auth' // get token from cookie
// import getPageTitle from '@/utils/get-page-title'

// NProgress.configure({ showSpinner: false }) // NProgress Configuration
const LocalUserInfo = Local.get("userInfo", true, true)
let getLocalTime = 0;
if (LocalUserInfo) {
  const localTime = Local.get('userInfo__expires__')
  const now = new Date().getTime()
  if (localTime && localTime > now) getLocalTime = Math.ceil((localTime - now) / 1000 / 60 / 60) || 1
  Session.set("userInfo", LocalUserInfo, true, (getLocalTime / 7) > 0 ? Math.ceil(60 * getLocalTime / 7): 60 * 6)
}

let refreshing = false // 是否正在更新过期token
export const refresh = function async(user, rToken, response) {
  if (refreshing) return
  refreshing = true
  return new Promise((resolve, reject) => {
    const userInfo = user.userInfo
    // 去服务器刷新token
    refreshToken({ refreshToken: rToken }).then(async (res) => {
      if (res?.errno === 0) {
        userInfo.accessToken = res.data.accessToken // 更新token后替换
        const getLocal = Local.get(user.userInfoSessionName, true, true)
        if (getLocal) {
          Local.set(user.userInfoSessionName, userInfo, true, getLocalTime > 0 ? Math.ceil(60 * getLocalTime) : 60 * 6)
        }
        Session.set(user.userInfoSessionName, userInfo, true, (getLocalTime / 7) > 0 ? Math.ceil(60 * getLocalTime / 7) : 60 * 6)
        store.commit('user/useDeCodeSetUserInfo', userInfo)
        await store.dispatch('user/reacquireUserInfo', userInfo)
        if (response) {
          axios.request(response.config)
        }
        refreshing = false
        return resolve(res)
      } else {
        refreshing = false
        return resolve(false)
      }
    }).catch(err => {
      refreshing = false
      return reject(err)
    });
  })
}
const whiteList = defaultRoute// no redirect whitelist
let isNextTo = false;
router.beforeEach(async (to, from, next) => {
  // start progress bar
  // NProgress.start()

  // set page title
  // document.title = getPageTitle(to.meta.title)
  // determine whether the user has logged in
  const hasToken = await Session.get('userInfo', true)
  const user = store.state.user
  const accessToken = user.userInfo.accessToken
  // debugger
  if (accessToken) {
    // 如果已经是登录状态、但是session的用户信息已过期，则通过刷新token把用户信息更新到session
    if (!hasToken && !refreshing) {
      await refresh(user, user.userInfo.refreshToken)
    }
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      // NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
    } else {
      // determine whether the user has obtained his permission roles through getInfo
      const hasRoles = store.getters['user/getUserInfo'].roleFlag
      if (hasRoles) {
        // 可以访问的页面缓存在Vuex中 判断是否有访问
        const routes = store.state.permission.routes
        if (routes.some(route => route.path == to.fullPath || route.path == to.path || route.name == to.name || route.path == to.matched?.[0]?.path)) {
          next()
        } else {
          // 修复使用url直接访问时，route没有获取到此路由的路由组件、路由名称。
          // 此处通过...to重新访问一次，再次进入routes.some判断。
          // 判断是否已经重定向过
          if (!to.name || isNextTo) {
            if(isNextTo) next({ path: '/', replace: true })
            isNextTo = true;
            next({ ...to })
          } else {
            next({ path: '/', replace: true })
          }
        }
      } else {
        try {
          // get user info
          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
          const { authNum } = await store.getters['user/getUserInfo']


          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', authNum)
          // dynamically add accessible routes
          router.addRoutes(accessRoutes)
          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          next({ ...to, replace: true })
        } catch (error) {
          // remove token and go to login page to re-login
          // await store.dispatch('user/resetToken')
          // Message.error(error || 'Has Error')
          // next(`/login?redirect=${to.path}`)
          next()
          // NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/
    // next()
    let path = to.path
    if (to.params.id) path = path.split(`/${to.params.id}`)[0]
    if (whiteList.indexOf(path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next({ name: "Login", params: { routePath: to.path, query: to.query } })
      // NProgress.done()
    }
  }
})

router.afterEach(() => {
  // finish progress bar
  // NProgress.done()
})